package com.lyf.controller;

import cn.hutool.core.util.BooleanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.lyf.DTO.SearchDTO;
import com.lyf.comon.ResponseResult;
import com.lyf.entity.*;
import com.lyf.service.*;
import com.lyf.service.impl.AdminServiceImpl;
import com.lyf.utils.WebUtils;
import com.lyf.vo.SearchResultVO;
import com.lyf.vo.SearchVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

import static com.lyf.constant.RedisConstants.CACHE_COLLECT_KEY;
import static com.lyf.constant.RedisConstants.CACHE_GIVEALIKE_KEY;

@RestController
@RequestMapping("/search")
public class SearchController {
    @Autowired
    private CarService carService;//车票
    @Autowired
    private RoutelService routelService;//路线
    @Autowired
    private HotelService hotelService;//住宿
    @Autowired
    private ScenicSpotService scenicSpotService;//景区
    @Autowired
    private InsuranceService insuranceService;//保险
    @Autowired
    private StrategyService strategyService;//攻略
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private AdminServiceImpl adminService;

    List<SearchResultVO>  searchResultVOS = new ArrayList<>();

    @PostMapping("/all")
    public ResponseResult searchAll(@RequestBody SearchDTO searchDTO) {
        System.out.println("关键词："+searchDTO.getSearchContent());

        searchResultVOS.clear(); // 清空数组

        //0车票
         carSearch(searchDTO);
        // 1路线
        routeSearch(searchDTO);
        // 2住宿
        hotelSearch(searchDTO);
        // 3景区
        scenicSearch(searchDTO);
        // 4保险
        insuranceSearch(searchDTO);
        // 5攻略
        strategySearch(searchDTO);

        if(searchResultVOS.size() > 0){
            return new ResponseResult(200,"搜索列表获取成功",searchResultVOS);
        }else if(searchResultVOS.size() == 0){
            return new ResponseResult(200,"没有该关键词的搜索记录！",searchResultVOS);
        }
        else{
            return ResponseResult.fail();
        }

    }
    //车票
    public void carSearch(SearchDTO searchDTO){
        String keyWord = searchDTO.getSearchContent();
        LambdaQueryWrapper<Car> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(StringUtils.isNotBlank(keyWord),Car::getTitle, keyWord);
        lambdaQueryWrapper.eq(Car::getState,1);
        List<Car> carList = carService.list(lambdaQueryWrapper);

        for (Car car : carList) {
             SearchVO searchVO = new SearchVO();
             searchVO.setId(car.getId());
             searchVO.setTypeId(0);
             searchVO.setTitle(car.getTitle());
             searchVO.setPrice(car.getPrice());
             searchVO.setStartDate(car.getStartDate());
             searchVO.setCarNumber(car.getTrainNumber());
             searchVO.setCarType(car.getType());
             searchVO.setNeedTime(car.getNeedTime());
             searchVO.setStartTime(car.getTimeRange());
             searchVO.setEndTime(car.getTimeEnd());
             searchVO.setStartSite(car.getStartPlace());
             searchVO.setEndSite(car.getEndPlace());

             SearchResultVO searchResultVO = new SearchResultVO();
             searchResultVO.setSearchVO(searchVO);
             searchResultVO.setLabel(car.getTitle());

            if (!searchResultVOS.contains(searchResultVO)) {
                searchResultVOS.add(searchResultVO);
            }
        }
    }

    //路线
    public void routeSearch(SearchDTO searchDTO){
        String keyWord = searchDTO.getSearchContent();
        LambdaQueryWrapper<Routel> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(StringUtils.isNotBlank(keyWord),Routel::getTitle, keyWord);
        lambdaQueryWrapper.eq(Routel::getState,1);
        List<Routel> routelList = routelService.list(lambdaQueryWrapper);

        for (Routel routel : routelList) {
            SearchVO searchVO = new SearchVO();
            searchVO.setId(routel.getId());
            searchVO.setTypeId(1);
            searchVO.setTitle(routel.getTitle());
            searchVO.setPrice(routel.getPrice());
            searchVO.setImgUrl(routel.getImgUrl());
            searchVO.setContent(routel.getIntro());
            searchVO.setStartDateTime(routel.getStartTime());
            searchVO.setEndDateTime(routel.getEndTime());
            searchVO.setStartSite(routel.getStartSite());
            searchVO.setEndSite(routel.getEndSite());
            searchVO.setDay(routel.getDay());

            SearchResultVO searchResultVO = new SearchResultVO();
            searchResultVO.setSearchVO(searchVO);
            searchResultVO.setLabel(routel.getTitle());

            if (!searchResultVOS.contains(searchResultVO)) {
                searchResultVOS.add(searchResultVO);
            }
        }
    }

    //住宿
    public void hotelSearch(SearchDTO searchDTO){
        String keyWord = searchDTO.getSearchContent();
        LambdaQueryWrapper<Hotel> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(StringUtils.isNotBlank(keyWord),Hotel::getHotelName, keyWord);
        lambdaQueryWrapper.eq(Hotel::getState,1);
        List<Hotel> hotelList = hotelService.list(lambdaQueryWrapper);

        for (Hotel hotel : hotelList) {
            SearchVO searchVO = new SearchVO();
            searchVO.setId(hotel.getId());
            searchVO.setTypeId(2);
            searchVO.setTitle(hotel.getHotelName());
            searchVO.setPrice(hotel.getPrice());
            searchVO.setImgUrl(hotel.getImgUrl());
            searchVO.setContent(hotel.getHotelIntro());
            searchVO.setScenicSpotId(hotel.getScenicSpotId());
            searchVO.setHotelStar(hotel.getHotelStar());
            searchVO.setAddress(hotel.getAddress());

            SearchResultVO searchResultVO = new SearchResultVO();
            searchResultVO.setSearchVO(searchVO);
            searchResultVO.setLabel(hotel.getHotelName());

            if (!searchResultVOS.contains(searchResultVO)) {
                searchResultVOS.add(searchResultVO);
            }
        }
    }

    //景区
    public void scenicSearch(SearchDTO searchDTO){
        String keyWord = searchDTO.getSearchContent();
        LambdaQueryWrapper<ScenicSpot> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(StringUtils.isNotBlank(keyWord),ScenicSpot::getSpotName, keyWord);
        lambdaQueryWrapper.eq(ScenicSpot::getState,1);
        List<ScenicSpot> scenicSpotList = scenicSpotService.list(lambdaQueryWrapper);

        for (ScenicSpot scenicSpot : scenicSpotList) {
            SearchVO searchVO = new SearchVO();
            searchVO.setId(scenicSpot.getId());
            searchVO.setTypeId(3);
            searchVO.setTitle(scenicSpot.getSpotName());
            searchVO.setPrice(scenicSpot.getTicketsMessage());
            searchVO.setImgUrl(scenicSpot.getImgUrl());
            searchVO.setContent(scenicSpot.getSpotIntro());
            searchVO.setHotelStar(scenicSpot.getSpotStar());
            searchVO.setAddress(scenicSpot.getSpotAddress());
            searchVO.setOpenTime(scenicSpot.getOpenTime());

            SearchResultVO searchResultVO = new SearchResultVO();
            searchResultVO.setSearchVO(searchVO);
            searchResultVO.setLabel(scenicSpot.getSpotName());

            if (!searchResultVOS.contains(searchResultVO)) {
                searchResultVOS.add(searchResultVO);
            }
        }
    }

    //保险
    public void insuranceSearch(SearchDTO searchDTO){
        String keyWord = searchDTO.getSearchContent();
        LambdaQueryWrapper<Insurance> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(StringUtils.isNotBlank(keyWord),Insurance::getTitle, keyWord);
        lambdaQueryWrapper.eq(Insurance::getState,1);
        List<Insurance> insuranceList = insuranceService.list(lambdaQueryWrapper);

        for (Insurance insurance : insuranceList) {
            SearchVO searchVO = new SearchVO();
            searchVO.setId(insurance.getId());
            searchVO.setTypeId(4);
            searchVO.setTitle(insurance.getTitle());
            searchVO.setPrice(insurance.getPrice());
            searchVO.setImgUrl(insurance.getImgUrl());
            searchVO.setContent(insurance.getResume());
            searchVO.setInsuranceType(insurance.getType());
            searchVO.setInsuranceCompany(insurance.getInsuranceCompany());

            SearchResultVO searchResultVO = new SearchResultVO();
            searchResultVO.setSearchVO(searchVO);
            searchResultVO.setLabel(insurance.getTitle());

            if (!searchResultVOS.contains(searchResultVO)) {
                searchResultVOS.add(searchResultVO);
            }
        }
    }

    //攻略
    public void strategySearch(SearchDTO searchDTO){
        String keyWord = searchDTO.getSearchContent();
        LambdaQueryWrapper<Strategy> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(StringUtils.isNotBlank(keyWord),Strategy::getTitle, keyWord);
        lambdaQueryWrapper.eq(Strategy::getState,1);
        List<Strategy> strategyList = strategyService.list(lambdaQueryWrapper);

        for (Strategy strategy : strategyList) {
            //查询攻略有关用户
            this.strategyUser(strategy);
            //判断攻略是否被点赞
            this.isStrategy(strategy);
            //判断攻略是否被收藏
            this.isCollect(strategy);

            SearchVO searchVO = new SearchVO();
            searchVO.setId(strategy.getId());
            searchVO.setTypeId(5);
            searchVO.setTitle(strategy.getTitle());
            searchVO.setAddTime(strategy.getAddTime());
            searchVO.setImgUrl(strategy.getImgUrl());
            searchVO.setUserUrl(strategy.getIcon());
            searchVO.setUserName(strategy.getUserName());
            searchVO.setIsLike(strategy.getIsLike());
            searchVO.setIsCollect(strategy.getIsCollect());
            searchVO.setLiked(strategy.getLiked());
            searchVO.setCollects(strategy.getCollects());

            SearchResultVO searchResultVO = new SearchResultVO();
            searchResultVO.setSearchVO(searchVO);
            searchResultVO.setLabel(strategy.getTitle());

            if (!searchResultVOS.contains(searchResultVO)) {
                searchResultVOS.add(searchResultVO);
            }
        }
    }



    private void strategyUser(Strategy strategy) {
        Long userId = strategy.getAddUserId();
        Admin admin = adminService.getById(userId);
        strategy.setUserName(admin.getUsername());
        strategy.setIcon(admin.getIcon());
    }

    //判断攻略是否被点赞
    private void isStrategy(Strategy strategy) {
        //1.获取登录用户
        Long userId = WebUtils.getUserId();
        //2.判断当前登录用户是否已经点赞
        String key = CACHE_GIVEALIKE_KEY + strategy.getId();
        Boolean isMember = redisTemplate.opsForSet().isMember(key, userId.toString());
        strategy.setIsLike(BooleanUtil.isTrue(isMember));

    }


    //判断收藏是否被收藏
    private void isCollect(Strategy strategy) {
        //1.获取登录用户
        Long userId = WebUtils.getUserId();
        //2.判断当前登录用户是否已经点赞
        String key = CACHE_COLLECT_KEY + strategy.getId();
        Boolean isMember = redisTemplate.opsForSet().isMember(key, userId.toString());
        strategy.setIsCollect(BooleanUtil.isTrue(isMember));
    }
}
